package com.xunfang.portal.runner;

/**
 * @author yellow Doctor
 * @date 2025-10-11
 * @desc https://blog.csdn.net/hekai7217
 */

import com.xunfang.common.BookConst;
import com.xunfang.common.RedisConst;
import com.xunfang.portal.model.entity.BookType;
import com.xunfang.portal.service.BookService;
import com.xunfang.portal.service.BookTypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;

/**
 * 书籍的任务类
 */
@Component
@EnableScheduling   //开启计划任务
@Slf4j   //记录日志
public class BookMallTask {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private BookService bookService;

    @Autowired
    private BookTypeService bookTypeService;

    /**
     * 更新热销榜和分类的Redis中数据
     *    热门数据优化:
     *        销量  +  浏览量 + 好评数 + 上架时间  =  热门商品数量
     *        60%      20%     15%      5%
     *             （redis统计）
     *        通过定时任务 解决数据更新排序
     */
    @Scheduled(cron = "0 0 0 * * ?")  // 每天凌晨0点执行，更新库存
//    @Scheduled(cron = "*/10 * * * * ?")  //测试：每过10秒执行一次
    public void updateHotSelling() {
        //1.删除所有以 "book:list" 开头的键
        deleteKeysWithPattern(RedisConst.BOOK_LIST + "*");
        //2.重新查询热销榜的数据到Redis中
        bookService.findTopSales(BookConst.FIRST_PAGE, BookConst.PAGE_SIZE);
        //3.查询所有的分类，将每个分类首页都更新到Redis中
        deleteKeysWithPattern(RedisConst.BOOK_TYPE_LIST + "*");
        List<BookType> bookTypes = bookTypeService.findAll();
        bookTypes.forEach(bookType -> {
            bookService.findByType(BookConst.FIRST_PAGE, BookConst.PAGE_SIZE, bookType.getId());
        });
        //3.记录日志
        log.info("成功更新热销榜的Redis中数据");
    }

    /**
     * 删除符合给定模式的key
     */
    public void deleteKeysWithPattern(String pattern) {
        //1. 获取所有符合这个模式的键
        Set<String> keys = redisTemplate.keys(pattern);
        //2.遍历并且删除这些键
        keys.forEach(key -> {
            redisTemplate.delete(key);
            log.info("删除键: {}", key);
        });
    }

}
